<?php
/**
 *
 * @category   babel 
 * @package    BABEL
 * @copyright  2008 Team babel
 * @license    LGPL
 */

/* {{{ Class for different checks/updates of translations, points */
class TranslationsPoints_Checks {

	public function __construct(){
	}

	/* {{{ Checks if a translations has enough points to be considered approved */
	public function checkTranslationApproved($transid, $userid, $points, $user_lang_skill){
		/* {{{ Inserts information into babel_votes */
		$DB_QUERY = "
		INSERT INTO
			babel_votes
				(ok,
				user_id,
				created,
				changed_date,
				translation_id)
		VALUES
			(?,
			?,
			NOW(),
			NOW(),
			?
			)";
		$success = PDODB::runQuery($DB_QUERY,array(BABEL_VOTE_OK_TRANSLATION, $userid, $transid));
		if (!$success) {
			throw new Exception("Query failed");
		}
		/* }}} */		
		
		$voting_points = TranslationsPoints_Checks::calculateUserPointsFromSkill($user_lang_skill);
		
		//The translation will get enough points to be approved
		if(($points + $voting_points) >= BABEL_POINTS_TO_APPROVE_VOTE){
			$DB_QUERY = "
			UPDATE
				babel_translations
			SET
				status = ?, 
				changed_date = NOW(),
				vote_points = vote_points + ?
			WHERE
				translation_id = ?
				";
			$success = PDODB::runQuery($DB_QUERY,array(BABEL_TRANSLATE_STATUS_APPROVED,$voting_points,
											$transid));
			if (!$success) {
				throw new Exception("Query failed");
			}
			
			//All right! Let`s give the user some points as well.
			TranslationsPoints_Checks::giveUserPoints($transid);
			
		//The translation won`t enough points to be approved
		} else {
			$DB_QUERY = "
			UPDATE
				babel_translations
			SET
				vote_points = vote_points + ?,
				changed_date = NOW()
			WHERE
				translation_id = ?";
			$success = PDODB::runQuery($DB_QUERY,array($voting_points, $transid));
			if (!$success) {
				throw new Exception("Query failed");
			}
		}
		
	}
	/* }}} */
	
	/* {{{ Gives the user experience points if he/she has contributed to a successful translation*/
	public function giveUserPoints($transid) {
		/*
		 * {{{ Get the user IDs that contributed to the vote
		 *     and check if they are on the correct translation or not
		 * 
		 */
		$success = PDODB::runQuery("
			SELECT 
				u.user_id AS id,
				skill AS skill, 
				lang_exp AS lang_exp,
				ok AS ok,
				t.language_id AS lang_id
			FROM 
				babel_user_skills u,
				babel_votes v,
				babel_translations t
			WHERE
				t.translation_id = ?
			AND
				u.user_id = v.user_id
			AND
				t.translation_id = v.translation_id
			AND
				t.language_id = u.language_id
			", array($transid), $stmt
		);
		/* }}} */

		/* {{{ Error handling */
		if (!$success) {
			Babel_Error_Logger::push($stmt->errorInfo());
			throw new BabelTranslateException("Odd results from DB");
		}
		/* }}} */
		
		/* {{{ Put the result in an array */
		foreach($stmt as $row) {
			$userinfo_array[] = array(
			    "id" 		=> $row["id"],
			    "skill" 	=> TranslationsPoints_Checks::calculateUserSkill($row["skill"], $row["ok"]),
			    "lang_exp" 	=> TranslationsPoints_Checks::calculateUserLangExp($row["lang_exp"], $row["ok"]),
			    "ok" 		=> $row["ok"],
				"lang_id"	=> $row["lang_id"]
			);
		}
		/* }}} */

		
		/*
		 * {{{ Get the user IDs that actually did the translation
		 *     (and the user IDs that contributed to the wrong translations)
		 * 
		 */
		$success = PDODB::runQuery("
			SELECT 
				u.user_id AS id,
				skill AS skill,
				t.status AS ok, 
				lang_exp AS lang_exp,
				t.language_id AS lang_id
			FROM 
				babel_user_skills u,
				babel_translations t
			WHERE
				t.value_id = (
					SELECT
						value_id
					FROM
						babel_translations
					WHERE
						translation_id = ?
					)
			AND
				u.user_id = t.user_id
			AND
				t.language_id = u.language_id
			", array($transid), $stmt
		);
		/* }}} */

		/* {{{ Error handling */
		if (!$success) {
			Babel_Error_Logger::push($stmt->errorInfo());
			throw new BabelTranslateException("Odd results from DB");
		}
		/* }}} */
		
		/* {{{ Put the result in an array */
		foreach($stmt as $row) {
			$userinfo_array[] = array(
			    "id" 		=> $row["id"],
			    "skill" 	=> TranslationsPoints_Checks::calculateUserSkill($row["skill"], $row["ok"]),
			    "lang_exp" 	=> TranslationsPoints_Checks::calculateUserLangExp($row["lang_exp"], $row["ok"]),
			    "ok" 		=> $row["ok"],
				"lang_id"	=> $row["lang_id"]
			);
		}
		/* }}} */

		//debugging
		Babel_Error_Logger::push($userinfo_array); 
		
		/* {{{ Insert the updated skill and experience points into the db */
			//FIXME: Is this possible in 1 sql query, not 50??
			foreach($userinfo_array as $arr) {
				$DB_QUERY = "
				UPDATE
					babel_user_skills
				SET
					lang_exp = ?,
					skill = ?
				WHERE
					user_id = ?
				AND
					language_id = ?
				";
				if (!PDODB::runQuery($DB_QUERY,array($arr["lang_exp"],$arr["skill"],$arr["id"],$arr["lang_id"]))) {
					throw new Exception("Query failed");
				}
			}
		/* }}} */
	}
	/* }}} */
	
	/* {{{ Calculates the skill of the user based upon if the vote was correct or not */
	private function calculateUserSkill($userskill, $ok) {
		/* {{{ The vote was correct */
		if($ok == 1 || $ok == 3) {
			if($userskill < BABEL_UPPER_LINEAR_SKILL_PROGRESS) {
				$userskill += BABEL_LINEAR_INCREMENT_VALUE;	
			} else {
				$userskill += (BABEL_NON_LINEAR_INCREMENT_VALUE / $userskill);
			}
		/* }}} */
		/* {{{ The vote was not correct */
		} else {
			$userskill - BABEL_WRONG_TRANSLATION;
		}
		/* }}} */
		
		/* {{{ Check if for legal values in $userskill, and deactivate the user if he is below the threshold */
		if($userskill < BABEL_MAX_USER_SKILL && $userskill >= BABEL_MIN_USER_SKILL){
			return $userskill;
		} else if ($userskill < BABEL_MIN_USER_SKILL) {
			//TODO: Deactivate user account.
			return BABEL_MIN_USER_SKILL;
		} else {
			return BABEL_MAX_USER_SKILL;	
		}
		/* }}} */
	}
	/* }}} */
	
	/* {{{ Calculates the users experience points in a language */
	private function calculateUserLangExp($userexp, $ok) {
		/* {{{ The vote was correct */
		if($ok == 1 || $ok == 3) {
			return $userexp + BABEL_POSITIVE_USER_EXP;
		/* }}} */
		/* {{{ The vote was not correct */
		} else {
			return $userexp - BABEL_NEGATIVE_USER_EXP;
		}
		/* }}} */
	}
	/* }}} */
	
	/* {{{ Checks the multiplier to use when calculating points to add to a vote in progress */
	private function calculateUserPointsFromSkill($user_lang_skill){		
		$points = $user_lang_skill -1;
		return $points;
	}
	/* }}} */
	
}
/*}}}*/

